﻿using System;
using System.Collections.Generic;
using System.Linq;
using JustinAngel.MetroBlog.Services.Data;
using JustinAngel.MetroBlog.Services.Repository;
using Microsoft.Practices.Unity;
using JustinAngel.MetroBlog.Common.Helpers;

namespace JustinAngel.MetroBlog.Services.BlogPostService
{
    public class BlogPostService : IBlogPostService
    {
        public BlogPost Find(int pk)
        {
            var ReturnValue = BlogPostRepository.Get().FirstOrDefault(b => b.ID == pk);

            ReturnValue.UserReference.Load();

            return ReturnValue;
        }

        public BlogPost Get(string permLink)
        {
            if (string.IsNullOrEmpty(permLink))
                return null;

            var ReturnValue = BlogPostRepositoryDefaultGet()
                                                 .FirstOrDefault(b => b.Permlink == permLink);
            return ReturnValue;
        }

        public BlogPost Get(string permLink, string username)
        {
            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(permLink))
                return Get(permLink);

            var ReturnValue = BlogPostRepositoryDefaultGet()
                                                .FirstOrDefault(b => b.Permlink == permLink
                                                                  && b.User.Username == username);
            return ReturnValue;
        }

        private IQueryable<BlogPost> BlogPostRepositoryDefaultGet()
        {
            return BlogPostRepository.Get()
                .With(b => b.PostCategories.Ignore().Category)
                .With(b => b.User)
                .With(b => b.Comments)
                .With(b => b.Comments.Ignore().ChildComments)
                ;
        }

        public void ClearCategoriesOn(BlogPost post)
        {
            post.PostCategories.Load();
            List<PostCategory> PostCategoriesToDelete = post.PostCategories.ToList();
            post.PostCategories.Clear();
            PostCategoriesToDelete.ForEach(a => a.Delete());
        }

        public List<BlogPost> GetHomePageBlogPosts()
        {
            var homeUser = UserRepository.Get().FirstOrDefault(u => u.IsDefaultBlog.Value);

            return ReturnHomePageBlogPostForUser(homeUser);
        }

        public List<BlogPost> SearchFor(string searchTerm, string username)
        {
            if (string.IsNullOrEmpty(username))
                return BlogPostRepositoryDefaultGet()
                                .Where(b => (b.HTML.Contains(searchTerm) || b.Title.Contains(searchTerm)))
                                .OrderByDescending(b => b.DateCreated)
                                .OrderByDescending(b => b.ID)
                                .ToList();
            else
                return BlogPostRepositoryDefaultGet()
                                                .Where(b => (b.HTML.Contains(searchTerm) 
                                                         || b.Title.Contains(searchTerm))
                                                           && b.User.Username == username)
                                                .OrderByDescending(b => b.DateCreated)
                                                .OrderByDescending(b => b.ID)
                                                .ToList();
        }

        public List<BlogPost> GetBlogPostsInCategory(string category, string username)
        {
            Category CurrentCategory = CategoryRepository.Get()
                                                         .FirstOrDefault(c => c.Name == category
                                                                      && c.User.Username == username);

            if (CurrentCategory == null)
                return null;

            return GetBlogPostsInCategory(CurrentCategory);
        }

        public List<BlogPost> GetBlogPostsInCategory(Category CurrentCategory)
        {
            return BlogPostRepositoryDefaultGet()
                .Where(b => b.PostCategories.Any(pc => pc.Category.ID == CurrentCategory.ID))
                .OrderByDescending(b => b.DateCreated)
                .ToList();
        }

        public bool Exists(string Permlink)
        {
            return BlogPostRepositoryDefaultGet().Any(b => b.Permlink == Permlink);
        }

        public List<BlogPost> GetUserByUserNameWithBlogPosts(string username)
        {
            User ReturnValue = UserRepository.Get().FirstOrDefault(u => u.Username == username);

            if (ReturnValue == null)
                return null;

            return ReturnHomePageBlogPostForUser(ReturnValue);
        }

        private List<BlogPost> ReturnHomePageBlogPostForUser(User ReturnValue)
        {
            int Take = ReturnValue.NumberOfBlogPostsOnHomePage.HasValue
                       && ReturnValue.NumberOfBlogPostsOnHomePage == 0
                           ? ReturnValue.NumberOfBlogPostsOnHomePage.Value
                           : 5;

            var HomePageBlogPosts = BlogPostRepositoryDefaultGet()
                .Where(b => b.User.ID == ReturnValue.ID)
                .OrderByDescending(b => b.DateCreated)
                .OrderByDescending(b => b.ID)
                .Take(Take)
                .ToList();

            return HomePageBlogPosts;
        }

        [Dependency]
        public IRepository<BlogPost> BlogPostRepository { get; set; }

        [Dependency]
        public IRepository<User> UserRepository { get; set; }

        [Dependency]
        public IRepository<Category> CategoryRepository { get; set; }
    }


}
